package com.huatai.dataservice.dubbo;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huatai.common.util.StringUtil;
import com.huatai.dataservice.entity.SubjectDataSetEntity;
import com.huatai.dataservice.mapper.TableQueryMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * @author gusiyi
 * @version 1.0
 * @className SubjectDataSetDubboImpl
 * @description 描述：
 * @date 2023/6/16 10:46
 */
@DubboService
@Slf4j
public class SubjectDataSetDubboImpl implements SubjectDataSetDubboApi {

	final String SELECT = "SELECT ";

	final String AS = " AS ";

	final String FROM = " FROM ";

	final String LIMIT = " LIMIT ";

	@Autowired
	private TableQueryMapper tableQueryMapper;

	@Override
	public Page<LinkedHashMap<String, Object>> getDataSetInfo(SubjectDataSetEntity dataSet) {
		String tableName = dataSet.getDataAccessTaskTable();
		boolean tableIsExist = tableQueryMapper.tableIsExist(tableName);
		if (!tableIsExist){
			throw new RuntimeException(dataSet.getSubjectDataSetName()+"关联的表"+tableName+"不存在");
		}
		List<LinkedHashMap<String, Object>> columns = tableQueryMapper.getColumns(tableName);
		List<String> columnList = new ArrayList<>(columns.size());
		List<String> commentList = new ArrayList<>(columns.size());
		for (Map<String, Object> column : columns) {
			columnList.add(column.get("COLUMN_NAME").toString());
			commentList.add(column.get("COLUMN_COMMENT").toString());
		}
		Integer pageIndex = dataSet.getPageIndex();
		Integer pageSize = dataSet.getPageSize();
		String sql = spliceSql(columnList, commentList, tableName, pageIndex, pageSize);
		sql = checkSqlStr(sql);
		Long count = tableQueryMapper.countByTableName(tableName);
		List<LinkedHashMap<String, Object>> resultList = tableQueryMapper.executeSql(sql);
		Page<LinkedHashMap<String,Object>> page = new Page<>();
		page.setRecords(resultList);
		page.setTotal(count);
		page.setSize(pageSize);
		page.setCurrent(pageIndex);
		page.setPages((count/pageSize)+1);
		return page;
	}

//	public String checkSqlStr(String sql){
//		if (sql.contains("loop AS")){
//			String regex = "\\bloop\\b(?=\\s*(AS|,|$))";
//			sql = sql.replaceAll(regex, "'loop'");
//			log.info("替换后的sql语句{}",sql);
//		}
//		if (sql.contains("range AS")){
//			String regex = "\\brange\\b(?=\\s*(AS|,|$))";
//			sql = sql.replaceAll(regex, "'range'");
//			log.info("替换后的sql语句{}",sql);
//		}
//		return sql;
//	}
	// 定义需要转义的MySQL保留字及其对应替换值（可扩展）
	private static final Map<String, String> RESERVED_WORDS = new LinkedHashMap<>();

	static {
		RESERVED_WORDS.put("loop", "`loop`");
		RESERVED_WORDS.put("range", "`range`");
		RESERVED_WORDS.put("require", "`require`");
		RESERVED_WORDS.put("finished", "`finished`");

		// 可在此继续添加其他保留字，如：
		// RESERVED_WORDS.put("group", "'group'");
		// RESERVED_WORDS.put("order", "'order'");
	}
	/**
	 * 描述: 替换保留字段
	 * 创建人: gaowengui
	 * 创建时间:  2025-05-14 10:50:22
	 * @param sql
	 * @return sql
	 **/
	public String checkSqlStr(String sql) {
		String processedSql = sql;
		for (Map.Entry<String, String> entry : RESERVED_WORDS.entrySet()) {
			String word = entry.getKey();
			String replacement = entry.getValue();
			// 构建正则表达式：精确匹配单词边界，且后面紧跟AS/逗号/结束符
			String regex = String.format(
				"(?i)\\b%s\\b(?=\\s*(AS|,|$))",
				Pattern.quote(word)  // 自动转义特殊字符
			);
			// 执行替换并保留原始大小写格式
			processedSql = Pattern.compile(regex)
				.matcher(processedSql)
				.replaceAll(replacement);

			log.info("保留字替换进度，当前处理词：{}，SQL状态：{}", word, processedSql);
		}
		return processedSql;
	}

	@Override
	public Long getDataSetCountByTableName(String tableName) {
		return tableQueryMapper.countByTableName(tableName);
	}

	/**
	 * 拼接查询sql
	 * @param columnList
	 * @param commentList
	 * @param tableName
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	private String spliceSql(List<String> columnList,List<String> commentList,String tableName,Integer pageIndex,Integer pageSize){
		StringBuilder spliceColumn = new StringBuilder();
		for (int i = 0; i < columnList.size(); i++) {
			spliceColumn
				.append(columnList.get(i))
				.append(AS)
				.append("'")
				.append(columnList.get(i));
			if (StringUtil.isNotBlank(commentList.get(i))){
				spliceColumn
					.append("(")
					.append(commentList.get(i))
					.append(")");
			}
			spliceColumn
				.append("',");
		}
		String columnSql = spliceColumn.substring(0, spliceColumn.length() - 1);
		String pageSql = ((pageIndex-1)*pageSize) + "," + pageSize;
		return SELECT + columnSql + FROM + tableName + LIMIT + pageSql;
	}
}
